"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const workspace_js_1 = __importDefault(require("./workspace.js"));
const geoserver_js_1 = require("./util/geoserver.js");
const about_js_1 = __importDefault(require("./about.js"));
class StyleClient {
    constructor(url, auth) {
        this.url = url;
        this.auth = auth;
    }
    async getDefaults() {
        const response = await fetch(this.url + 'styles.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.json();
    }
    async getInWorkspace(workspace) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/styles.json', {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
        return response.json();
    }
    async getAllWorkspaceStyles() {
        const allStyles = [];
        const ws = new workspace_js_1.default(this.url, this.auth);
        const allWs = await ws.getAll();
        if (!allWs ||
            !allWs.workspaces ||
            !allWs.workspaces.workspace ||
            !Array.isArray(allWs.workspaces.workspace)) {
            throw new geoserver_js_1.GeoServerResponseError('Response of available workspaces is malformed');
        }
        for (let i = 0; i < allWs.workspaces.workspace.length; i++) {
            const ws = allWs.workspaces.workspace[i];
            const wsStyles = await this.getInWorkspace(ws.name);
            if (wsStyles.styles.style) {
                wsStyles.styles.style.forEach(wsStyle => {
                    allStyles.push(wsStyle);
                });
            }
        }
        return allStyles;
    }
    async getAll() {
        const defaultStyles = await this.getDefaults();
        const wsStyles = await this.getAllWorkspaceStyles();
        if (!defaultStyles ||
            !defaultStyles.styles ||
            !defaultStyles.styles.style ||
            !Array.isArray(defaultStyles.styles.style)) {
            throw new geoserver_js_1.GeoServerResponseError('Response of default styles malformed');
        }
        const allStyles = defaultStyles.styles.style.concat(wsStyles);
        return allStyles;
    }
    async publish(workspace, name, sldBody) {
        const response = await fetch(this.url + 'workspaces/' + workspace + '/styles?name=' + name, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/vnd.ogc.sld+xml'
            },
            body: sldBody
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async delete(workspace, name, recurse, purge) {
        let paramPurge = false;
        let paramRecurse = false;
        if (purge === true) {
            paramPurge = true;
        }
        if (recurse === true) {
            paramRecurse = true;
        }
        let endpoint;
        if (workspace) {
            endpoint = this.url + 'workspaces/' + workspace + '/styles/' + name +
                '?' + 'purge=' + paramPurge + '&' + 'recurse=' + paramRecurse;
        }
        else {
            endpoint = this.url + 'styles/' + name +
                '?' + 'purge=' + paramPurge + '&' + 'recurse=' + paramRecurse;
        }
        const response = await fetch(endpoint, {
            credentials: 'include',
            method: 'DELETE',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            switch (response.status) {
                case 403:
                    throw new geoserver_js_1.GeoServerResponseError('Deletion failed. There might be dependant layers to this style. Delete them first or call this with "recurse=false"', geoServerResponse);
                default:
                    throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
    }
    async assignStyleToLayer(workspaceOfLayer, layerName, workspaceOfStyle, styleName, isDefaultStyle) {
        let qualifiedName;
        if (workspaceOfLayer) {
            qualifiedName = `${workspaceOfLayer}:${layerName}`;
        }
        else {
            qualifiedName = layerName;
        }
        const styleBody = await this.getStyleInformation(workspaceOfStyle, styleName);
        let url;
        if (isDefaultStyle !== false) {
            url = this.url + 'layers/' + qualifiedName + '/styles?default=true';
        }
        else {
            url = this.url + 'layers/' + qualifiedName + '/styles';
        }
        const response = await fetch(url, {
            credentials: 'include',
            method: 'POST',
            headers: {
                Authorization: this.auth,
                'content-type': 'application/json'
            },
            body: JSON.stringify(styleBody)
        });
        if (!response.ok) {
            const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
            throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
        }
    }
    async getStyleInformation(workspace, styleName) {
        let url;
        if (workspace) {
            url = this.url + 'workspaces/' + workspace + '/styles/' + styleName + '.json';
        }
        else {
            url = this.url + 'styles/' + styleName + '.json';
        }
        const response = await fetch(url, {
            credentials: 'include',
            method: 'GET',
            headers: {
                Authorization: this.auth
            }
        });
        if (!response.ok) {
            const grc = new about_js_1.default(this.url, this.auth);
            if (await grc.exists()) {
                return;
            }
            else {
                const geoServerResponse = await (0, geoserver_js_1.getGeoServerResponseText)(response);
                throw new geoserver_js_1.GeoServerResponseError(null, geoServerResponse);
            }
        }
        return response.json();
    }
}
exports.default = StyleClient;
